package org.wu.framework.lazy.orm.core.source.h2;


import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.wu.framework.core.NormalUsedString;
import org.wu.framework.core.stereotype.LayerField;
import org.wu.framework.core.utils.ObjectUtils;
import org.wu.framework.lazy.orm.core.persistence.conf.LazyDatabaseJsonMessage;
import org.wu.framework.lazy.orm.core.persistence.conf.LazyTableEndpoint;
import org.wu.framework.lazy.orm.core.persistence.conf.LazyTableFieldEndpoint;
import org.wu.framework.lazy.orm.core.persistence.conf.clazz.AbstractLazyTableEndpoint;

import java.text.Collator;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;


/**
 * Java class 转化成 h2 表信息
 *
 * @author : Jia wei Wu
 * @version : 1.0
 * @date : 2022/1/23 4:39 下午
 */
@Slf4j
@Data
public class H2TableLazyTableEndpoint extends AbstractLazyTableEndpoint<H2ColumnEndpoint> {

    /**
     * 字段
     */
    private List<H2ColumnEndpoint> lazyTableFieldEndpointList;

    /**
     * 创建表语句
     * <p>
     * -- auto-generated definition
     * create table TABLE_NAME
     * (
     * ID          INTEGER auto_increment,
     * COLUMN_NAME CHARACTER VARYING
     * );
     * <p>
     * comment on table TABLE_NAME is '你好这是表注释';
     * <p>
     * comment on column TABLE_NAME.ID is 'id';
     * </p>
     *
     * @return
     */
    @Override
    public String creatTableSQL() {
        StringBuilder createTableSQLBuffer = new StringBuilder(
                String.format(LazyTableEndpoint.SQL_DESC, getFullTableName(), getComment(), LazyTableEndpoint.AUTHOR, LocalDate.now()));

        if (!ObjectUtils.isEmpty(getSchema())) {
            createTableSQLBuffer.append(String.format(" CREATE DATABASE IF NOT EXISTS %s; \n use %s ; \n ", getSchema(), getSchema()));
        }
//        createTableSQLBuffer.append(String.format(SQLAnalyze.SQL_DROP, getTableName()));


        createTableSQLBuffer.append("CREATE TABLE IF NOT EXISTS \"")
                .append(getTableName()).append("\" ( \n");
        List<H2ColumnEndpoint> fieldEndpoints = getLazyTableFieldEndpointList();
        // 添加额外的模型字段
        List<H2ColumnEndpoint> fieldLazyTableFieldEndpointList = new ArrayList<>(fieldEndpoints);
        fieldLazyTableFieldEndpointList.addAll(
                LazyDatabaseJsonMessage.extraFields.stream().map(fieldLazyTableFieldEndpoint -> {
                    if (null == fieldLazyTableFieldEndpoint) {
                        return null;
                    }
                    H2ColumnEndpoint h2ColumnEndpoint = new H2ColumnEndpoint();
                    h2ColumnEndpoint.setNotNull(fieldLazyTableFieldEndpoint.isNotNull());
                    h2ColumnEndpoint.setDefaultValue(fieldLazyTableFieldEndpoint.getDefaultValue());
                    h2ColumnEndpoint.setKey(fieldLazyTableFieldEndpoint.isKey());
                    h2ColumnEndpoint.setSerialNumber(fieldLazyTableFieldEndpoint.getSerialNumber());
                    h2ColumnEndpoint.setName(fieldLazyTableFieldEndpoint.getName());
                    h2ColumnEndpoint.setColumnName(fieldLazyTableFieldEndpoint.getColumnName());
                    h2ColumnEndpoint.setAlias(fieldLazyTableFieldEndpoint.getAlias());
                    h2ColumnEndpoint.setColumnType(fieldLazyTableFieldEndpoint.getColumnType());
                    h2ColumnEndpoint.setClazz(fieldLazyTableFieldEndpoint.getClazz());
                    h2ColumnEndpoint.setComment(fieldLazyTableFieldEndpoint.getComment());
                    h2ColumnEndpoint.setExist(fieldLazyTableFieldEndpoint.isExist());
                    h2ColumnEndpoint.setUpsertStrategy(fieldLazyTableFieldEndpoint.getUpsertStrategy());
                    h2ColumnEndpoint.setUpdateStrategy(fieldLazyTableFieldEndpoint.getUpdateStrategy());
                    h2ColumnEndpoint.setExtra(fieldLazyTableFieldEndpoint.getExtra());
                    h2ColumnEndpoint.setPrivileges(fieldLazyTableFieldEndpoint.getPrivileges());
                    h2ColumnEndpoint.setLazyTableIndexEndpoints(fieldLazyTableFieldEndpoint.getLazyTableIndexEndpoints());
                    h2ColumnEndpoint.setVersion(fieldLazyTableFieldEndpoint.getVersion());
                    h2ColumnEndpoint.setScale(fieldLazyTableFieldEndpoint.getScale());
                    h2ColumnEndpoint.setParameters(fieldLazyTableFieldEndpoint.getParameters());
                    h2ColumnEndpoint.setOptional(fieldLazyTableFieldEndpoint.isOptional());
                    h2ColumnEndpoint.setFieldDefaultValue(fieldLazyTableFieldEndpoint.getFieldDefaultValue());
                    h2ColumnEndpoint.setIEnum(fieldLazyTableFieldEndpoint.getIEnum());
                    h2ColumnEndpoint.setDataType(fieldLazyTableFieldEndpoint.getDataType());
                    h2ColumnEndpoint.setConvertContentSeparator(fieldLazyTableFieldEndpoint.getConvertContentSeparator());
                    h2ColumnEndpoint.setConvert(fieldLazyTableFieldEndpoint.getConvert());
                    h2ColumnEndpoint.setFieldValue(fieldLazyTableFieldEndpoint.getFieldValue());
                    h2ColumnEndpoint.setField(fieldLazyTableFieldEndpoint.getField());
                    h2ColumnEndpoint.setIdType(fieldLazyTableFieldEndpoint.getIdType());
                    return h2ColumnEndpoint;
                }).toList()
        );
        fieldLazyTableFieldEndpointList = fieldLazyTableFieldEndpointList.stream().sorted(
                        (firstLazyTableFieldEndpoint, secondLazyFieldLazyTableFieldEndpoint) ->
                                Collator.getInstance(Locale.CHINA)
                                        .compare(firstLazyTableFieldEndpoint.getColumnName(), secondLazyFieldLazyTableFieldEndpoint.getColumnName()))
                .collect(
                        Collectors.collectingAndThen(Collectors.toCollection(() ->
                                        new TreeSet<>(Comparator.comparing(LazyTableFieldEndpoint::getColumnName))),
                                ArrayList::new));

        // 是否为唯一索引
        List<String> uniqueList = fieldLazyTableFieldEndpointList.stream().
                filter(LazyTableFieldEndpoint::isExist).
                filter(field -> Arrays.stream(field.getLazyTableIndexEndpoints()).anyMatch(index -> LayerField.LayerFieldType.UNIQUE.equals(index.getFieldIndexType()))).
                map(LazyTableFieldEndpoint::getColumnName).toList();

        // 所有的索引
        Map<LayerField.LayerFieldType, Map<String, List<LazyTableFieldEndpoint>>> layerFieldTypeMap = getLayerFieldTypeMap(fieldLazyTableFieldEndpointList);

        // 字段数据
        List<String> columnList = new ArrayList<>();
        // 添加字段

        fieldLazyTableFieldEndpointList.stream().
                filter(LazyTableFieldEndpoint::isExist).
                forEach(field -> columnList.add(field.columnSQL() + NormalUsedString.NEWLINE));
        // 主键 PRIMARY KEY (\"id\")
//        List<String> idList = fieldLazyTableFieldEndpointList.stream().
//                filter(LazyTableFieldEndpoint::isExist).
//                filter(LazyTableFieldEndpoint::isKey).
//                map(LazyTableFieldEndpoint::getColumnName).toList();


//        if (!ObjectUtils.isEmpty(idList)) {
//            columnList.add(String.format("PRIMARY KEY (%s) ", String.join(NormalUsedString.COMMA, idList)) + NormalUsedString.NEWLINE);
//        }


        createTableSQLBuffer.append(String.join(NormalUsedString.COMMA, columnList));

        createTableSQLBuffer.append(")");
//        createTableSQLBuffer.append(") ENGINE=");
//        createTableSQLBuffer.append(getEngine().getName());
//        createTableSQLBuffer.append(" DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='");
//        createTableSQLBuffer.append(getComment());
        createTableSQLBuffer.append(";\n");

        // 索引

        if (!ObjectUtils.isEmpty(layerFieldTypeMap)) {
            // 唯一性索引
            Map<String, List<LazyTableFieldEndpoint>> uniqueIndexMap = layerFieldTypeMap.get(LayerField.LayerFieldType.UNIQUE);
            //        create unique index lazy_netty_client_blacklist_CLIENT_ID_IS_DELETED_UNINDEX
            //    on lazy_netty_client_blacklist (CLIENT_ID, IS_DELETED);
            if (!ObjectUtils.isEmpty(uniqueIndexMap)) {
                uniqueIndexMap.forEach((uniqueIndexName, lazyTableFieldEndpoints) -> {
                    String uniqueIndexSql = "CREATE UNIQUE INDEX IF NOT EXISTS " + uniqueIndexName + NormalUsedString.SPACE + NormalUsedString.ON + NormalUsedString.SPACE + getTableName() + " (" +
                            lazyTableFieldEndpoints.stream().map(LazyTableFieldEndpoint::getColumnName
                            ).collect(Collectors.joining(","))
                            + ");" + NormalUsedString.NEWLINE;

                    createTableSQLBuffer.append(uniqueIndexSql);

                });
            }
            // Normal索引
            Map<String, List<LazyTableFieldEndpoint>> normalIndexMap = layerFieldTypeMap.get(LayerField.LayerFieldType.NORMAL);
            //    create index PRIMARY_KEY_4
            //    on EMPLOYEES (ID, DEPARTMENT_ID);
            if (!ObjectUtils.isEmpty(normalIndexMap)) {
                normalIndexMap.forEach((normalIndexName, lazyTableFieldEndpoints) -> {
                    String normalIndexSql = " CREATE INDEX " + normalIndexName + NormalUsedString.SPACE + NormalUsedString.ON + NormalUsedString.SPACE + getTableName() + " (" +
                            lazyTableFieldEndpoints.stream().map(LazyTableFieldEndpoint::getColumnName
                            ).collect(Collectors.joining(","))
                            + ");" + NormalUsedString.NEWLINE;
                    createTableSQLBuffer.append(normalIndexSql);

                });
            }
            // fulltext 全文索引
            Map<String, List<LazyTableFieldEndpoint>> fulltextIndexMap = layerFieldTypeMap.get(LayerField.LayerFieldType.FULLTEXT);
            //    create index PRIMARY_KEY_4
            //    on EMPLOYEES (ID, DEPARTMENT_ID);
            if (!ObjectUtils.isEmpty(fulltextIndexMap)) {
                fulltextIndexMap.forEach((fulltextIndexName, lazyTableFieldEndpoints) -> {
                    String fulltextIndexSql = " CREATE INDEX " + fulltextIndexName + NormalUsedString.SPACE + NormalUsedString.ON + NormalUsedString.SPACE + getTableName() + " (" +
                            lazyTableFieldEndpoints.stream().map(LazyTableFieldEndpoint::getColumnName
                            ).collect(Collectors.joining(","))
                            + ");" + NormalUsedString.NEWLINE;
                    createTableSQLBuffer.append(fulltextIndexSql);
                });
            }
        }
        // 空间索引
        Map<String, List<LazyTableFieldEndpoint>> spatialIndexMap = layerFieldTypeMap.get(LayerField.LayerFieldType.SPATIAL);
        //    create index PRIMARY_KEY_4
        //    on EMPLOYEES (ID, DEPARTMENT_ID);
        if (!ObjectUtils.isEmpty(spatialIndexMap)) {
            spatialIndexMap.forEach((spatialIndexName, lazyTableFieldEndpoints) -> {
                String spatialIndexSql = " CREATE INDEX " + spatialIndexName + NormalUsedString.SPACE + NormalUsedString.ON + NormalUsedString.SPACE + getTableName() + " (" +
                        lazyTableFieldEndpoints.stream().map(LazyTableFieldEndpoint::getColumnName
                        ).collect(Collectors.joining(","))
                        + ");" + NormalUsedString.NEWLINE;
                createTableSQLBuffer.append(spatialIndexSql);
            });
        }

        createTableSQLBuffer.append("-- ------end \n" +
                "-- ——————————————————————————\n");
        System.out.println(createTableSQLBuffer);
        return createTableSQLBuffer.toString();
    }

    /**
     * // 添加列
     * //        ALTER TABLE tableName
     * //      ADD columnName VARCHAR(255) 'comment'
     *
     * @param currentColumnNameList 当前字段
     * @return
     * @author Jiawei Wu
     * @date 2020/12/31 9:32 下午
     **/
    /**
     * ♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬
     * ♬                                                                                                                                              ♬
     * ♬                                                                                                                                              ♬
     * ♬                                                                                                                                               ♬
     * ♬                                                                                                                                              ♬
     * ♬                                                                                                                                              ♬
     * ♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬♬
     *
     * @param currentColumnNameList 当前数据库字段
     * @param dropColumn            是否删除列
     */
    @Override
    public String alterTableSQL(List<H2ColumnEndpoint> currentColumnNameList, boolean dropColumn) {
        currentColumnNameList =
                currentColumnNameList
                        .stream()
                        .sorted((fieldLazyTableFieldEndpoint1, fieldLazyTableFieldEndpoint2) ->
                                Collator.getInstance(Locale.CHINA)
                                        .compare(fieldLazyTableFieldEndpoint1.getColumnName(), fieldLazyTableFieldEndpoint2.getColumnName()))
                        .collect(Collectors.toList());
        // 最终的两段sql  添加字sql和更改sql
        List<String> alterTableColumnSQLPartList = alterTableColumnSQLPartList(currentColumnNameList, dropColumn);

        if (ObjectUtils.isEmpty(alterTableColumnSQLPartList)) {
            return null;
        }

        String alterSQL = alterTableColumnSQLPartList
                .stream()
                .filter(alertSql -> !ObjectUtils.isEmpty(alertSql))
                .collect(Collectors.joining(NormalUsedString.SEMICOLON + NormalUsedString.NEWLINE));
        log.debug("更新表结构语句:{}", alterSQL);
        return alterSQL;
    }

    /**
     * 获取 更改的表字段 如 MODIFY COLUMN is_deleted TINYINT ( 1 ) DEFAULT '0' COMMENT '是否删除',
     *
     * @param currentColumnNameList 当前数据库字段
     * @param dropColumn            是否删除列
     * @return
     */
    @Override
    protected List<String> alterTableColumnSQLPartList(List<H2ColumnEndpoint> currentColumnNameList, boolean dropColumn) {
        currentColumnNameList = currentColumnNameList.stream().sorted((fieldLazyTableFieldEndpoint1, fieldLazyTableFieldEndpoint2) -> Collator.getInstance(Locale.CHINA).compare(fieldLazyTableFieldEndpoint1.getColumnName(), fieldLazyTableFieldEndpoint2.getColumnName())).collect(Collectors.toList());

        // alert table xx
        String alertTablePre = NormalUsedString.ALTER + NormalUsedString.SPACE + NormalUsedString.TABLE + NormalUsedString.SPACE + getFullTableName() + NormalUsedString.SPACE;

        //  添加字段 字段名 字段类型 字段备注
        String ADD_FIELD = " ADD %s %s comment '%s' ";

        // 实体对应的模型字段
        // 添加额外的模型字段
        List<H2ColumnEndpoint> javaFieldLazyTableFieldEndpointList = getLazyTableFieldEndpointList().stream().sorted((fieldLazyTableFieldEndpoint1, fieldLazyTableFieldEndpoint2) -> Collator.getInstance(Locale.CHINA).compare(fieldLazyTableFieldEndpoint1.getColumnName(), fieldLazyTableFieldEndpoint2.getColumnName())).collect(Collectors.toList());
        javaFieldLazyTableFieldEndpointList.addAll(
                LazyDatabaseJsonMessage.extraFields.stream().map(fieldLazyTableFieldEndpoint -> {
                    if (null == fieldLazyTableFieldEndpoint) {
                        return null;
                    }
                    H2ColumnEndpoint h2ColumnEndpoint = new H2ColumnEndpoint();
                    h2ColumnEndpoint.setNotNull(fieldLazyTableFieldEndpoint.isNotNull());
                    h2ColumnEndpoint.setDefaultValue(fieldLazyTableFieldEndpoint.getDefaultValue());
                    h2ColumnEndpoint.setKey(fieldLazyTableFieldEndpoint.isKey());
                    h2ColumnEndpoint.setSerialNumber(fieldLazyTableFieldEndpoint.getSerialNumber());
                    h2ColumnEndpoint.setName(fieldLazyTableFieldEndpoint.getName());
                    h2ColumnEndpoint.setColumnName(fieldLazyTableFieldEndpoint.getColumnName());
                    h2ColumnEndpoint.setAlias(fieldLazyTableFieldEndpoint.getAlias());
                    h2ColumnEndpoint.setColumnType(fieldLazyTableFieldEndpoint.getColumnType());
                    h2ColumnEndpoint.setClazz(fieldLazyTableFieldEndpoint.getClazz());
                    h2ColumnEndpoint.setComment(fieldLazyTableFieldEndpoint.getComment());
                    h2ColumnEndpoint.setExist(fieldLazyTableFieldEndpoint.isExist());
                    h2ColumnEndpoint.setUpsertStrategy(fieldLazyTableFieldEndpoint.getUpsertStrategy());
                    h2ColumnEndpoint.setUpdateStrategy(fieldLazyTableFieldEndpoint.getUpdateStrategy());
                    h2ColumnEndpoint.setExtra(fieldLazyTableFieldEndpoint.getExtra());
                    h2ColumnEndpoint.setPrivileges(fieldLazyTableFieldEndpoint.getPrivileges());
                    h2ColumnEndpoint.setLazyTableIndexEndpoints(fieldLazyTableFieldEndpoint.getLazyTableIndexEndpoints());
                    h2ColumnEndpoint.setVersion(fieldLazyTableFieldEndpoint.getVersion());
                    h2ColumnEndpoint.setScale(fieldLazyTableFieldEndpoint.getScale());
                    h2ColumnEndpoint.setParameters(fieldLazyTableFieldEndpoint.getParameters());
                    h2ColumnEndpoint.setOptional(fieldLazyTableFieldEndpoint.isOptional());
                    h2ColumnEndpoint.setFieldDefaultValue(fieldLazyTableFieldEndpoint.getFieldDefaultValue());
                    h2ColumnEndpoint.setIEnum(fieldLazyTableFieldEndpoint.getIEnum());
                    h2ColumnEndpoint.setDataType(fieldLazyTableFieldEndpoint.getDataType());
                    h2ColumnEndpoint.setConvertContentSeparator(fieldLazyTableFieldEndpoint.getConvertContentSeparator());
                    h2ColumnEndpoint.setConvert(fieldLazyTableFieldEndpoint.getConvert());
                    h2ColumnEndpoint.setFieldValue(fieldLazyTableFieldEndpoint.getFieldValue());
                    h2ColumnEndpoint.setField(fieldLazyTableFieldEndpoint.getField());
                    h2ColumnEndpoint.setIdType(fieldLazyTableFieldEndpoint.getIdType());
                    return h2ColumnEndpoint;
                }).toList()
        );
        javaFieldLazyTableFieldEndpointList = javaFieldLazyTableFieldEndpointList.stream().collect(
                Collectors.collectingAndThen(Collectors.toCollection(() ->
                                new TreeSet<>(Comparator.comparing(LazyTableFieldEndpoint::getColumnName))),
                        ArrayList::new));

        // 当前数据库包含的字段
        Map<String, LazyTableFieldEndpoint> currentColumnNameMap = currentColumnNameList.stream().
                collect(Collectors.toMap(lazyTableFieldEndpoint -> lazyTableFieldEndpoint.getColumnName().toLowerCase(Locale.ROOT), convertedField -> convertedField, (A, B) -> A));

        List<String> ADD_SQL_LIST = javaFieldLazyTableFieldEndpointList.stream().
                filter(field -> !currentColumnNameMap.containsKey(field.getColumnName().toLowerCase(Locale.ROOT))).
                map(convertedField -> String.format(ADD_FIELD,
                        convertedField.getColumnName(),
                        convertedField.getColumnType(),
                        convertedField.getComment())
                ).
                collect(Collectors.toList());

        List<String> modifySqlList = new ArrayList<>();

        for (LazyTableFieldEndpoint fieldEndpoint : javaFieldLazyTableFieldEndpointList) {
            // 数据库字段
            String currentColumnName = fieldEndpoint.getColumnName().replaceAll(NormalUsedString.BACKTICK, NormalUsedString.EMPTY);
            // 数据库没有的字段不修改
            if (!currentColumnNameMap.containsKey(currentColumnName)) {
                continue;
            }
            LazyTableFieldEndpoint mysqlFieldEndpoint = currentColumnNameMap.get(currentColumnName);
            String comment = fieldEndpoint.getComment();
            // 判断数据不一致
            if (
                // 非空比较
                    mysqlFieldEndpoint.isNotNull() == fieldEndpoint.isNotNull()
                            // 默认值比较
                            && Objects.equals(mysqlFieldEndpoint.getDefaultValue(), fieldEndpoint.getDefaultValue())
                            // 描述比较
                            && Objects.equals(mysqlFieldEndpoint.getComment(), comment)
                            // 主键比较
                            && fieldEndpoint.isKey() == mysqlFieldEndpoint.isKey()
                            // 额外字段比较
                            && Objects.equals(fieldEndpoint.getExtra(), mysqlFieldEndpoint.getExtra())
                            // 字段类型比较
                            && Objects.equals(fieldEndpoint.getColumnType().replaceAll(NormalUsedString.SPACE, NormalUsedString.EMPTY), mysqlFieldEndpoint.getColumnType().replaceAll(NormalUsedString.SPACE, NormalUsedString.EMPTY)) // varchar(255 ) 与varchar(255)
            ) {
                continue;
            }
            modifySqlList.add(alertTablePre + fieldEndpoint.modifyColumnSQL());
        }

        // 删除列
        if (dropColumn) {
            // DROP COLUMN \"request_methods\"
            List<H2ColumnEndpoint> finalJavaFieldLazyTableFieldEndpointList = javaFieldLazyTableFieldEndpointList;
            currentColumnNameList.stream().
                    filter(lazyTableFieldEndpoint -> !finalJavaFieldLazyTableFieldEndpointList.
                            stream().
                            map(LazyTableFieldEndpoint::getColumnName).toList()
                            .contains(lazyTableFieldEndpoint.getColumnName())
                    )
                    .forEach(lazyTableFieldEndpoint -> modifySqlList.add(alertTablePre + lazyTableFieldEndpoint.dropColumnSQL()));
        }
        // 主键索引比较

        String currentColumnPkIndex = currentColumnNameList
                .stream()
                .filter(LazyTableFieldEndpoint::isKey).
                map(LazyTableFieldEndpoint::getColumnName).
                collect(Collectors.joining(NormalUsedString.UNDERSCORE));

        String javaColumnPkIndex = javaFieldLazyTableFieldEndpointList
                .stream()
                .filter(LazyTableFieldEndpoint::isKey).
                map(LazyTableFieldEndpoint::getColumnName).
                collect(Collectors.joining(NormalUsedString.UNDERSCORE));
        // 默认主键不删除
        if (!Objects.equals(currentColumnPkIndex, javaColumnPkIndex)) {
            //DROP PRIMARY KEY,
            //ADD PRIMARY KEY (\"application_id\", \"database_schema_id\", \"is_deleted\") USING BTREE;

            // 有主键且更改、删除原主键
            if (currentColumnNameList.stream().anyMatch(LazyTableFieldEndpoint::isKey)) {
                modifySqlList.add("DROP PRIMARY KEY ON " + getFullTableName());
            }
            if (!ObjectUtils.isEmpty(javaColumnPkIndex)) {
                String pk = javaFieldLazyTableFieldEndpointList.stream().filter(LazyTableFieldEndpoint::isKey).
                        map(LazyTableFieldEndpoint::getColumnName).
                        collect(Collectors.joining(NormalUsedString.COMMA));
                modifySqlList.add(alertTablePre + String.format("ADD PRIMARY KEY (%s) ", pk));
            }

        }
        // 当前数据库对应索引数据结构
        Map<LayerField.LayerFieldType, Map<String, List<LazyTableFieldEndpoint>>>
                currentLayerFieldTypeMap =
                getLayerFieldTypeMap(currentColumnNameList);

        // 当前Java对应索引数据结构
        Map<LayerField.LayerFieldType, Map<String, List<LazyTableFieldEndpoint>>> javaLayerFieldTypeMap
                = getLayerFieldTypeMap(javaFieldLazyTableFieldEndpointList);


        // 索引比较
        // 唯一性索引

        Map<String, List<LazyTableFieldEndpoint>> currentColumnUniqueIndex = currentLayerFieldTypeMap.get(LayerField.LayerFieldType.UNIQUE);

        Map<String, List<LazyTableFieldEndpoint>> javaColumnUniqueIndex = javaLayerFieldTypeMap.get(LayerField.LayerFieldType.UNIQUE);
        if (!ObjectUtils.isEmpty(javaColumnUniqueIndex)) {
            javaColumnUniqueIndex.forEach((indexName, lazyTableFieldEndpoints) -> {
                indexName = ObjectUtils.isEmpty(indexName) ?
                        lazyTableFieldEndpoints.stream().map(lazyTableFieldEndpoint -> lazyTableFieldEndpoint.getColumnName().replaceAll(NormalUsedString.BACKTICK, NormalUsedString.EMPTY).substring(0, 1))
                                .collect(Collectors.joining(NormalUsedString.UNDERSCORE)) :
                        indexName;
                if (!ObjectUtils.isEmpty(currentColumnUniqueIndex) && currentColumnUniqueIndex.containsKey(indexName)) {
                    // 判断是否修改索引
                    List<LazyTableFieldEndpoint> indexLazyTableFieldEndpoints = currentColumnUniqueIndex.get(indexName);

                    // 重复数据
                    ArrayList<LazyTableFieldEndpoint> duplicateList = new ArrayList<>(lazyTableFieldEndpoints);
                    duplicateList.addAll(indexLazyTableFieldEndpoints);
                    ArrayList<LazyTableFieldEndpoint> tableFieldEndpointArrayList = duplicateList.stream().collect(
                            Collectors.collectingAndThen(Collectors.toCollection(() ->
                                            new TreeSet<>(Comparator.comparing(LazyTableFieldEndpoint::getColumnName))),
                                    ArrayList::new));
                    // 不完全重复
                    if (!ObjectUtils.isEmpty(tableFieldEndpointArrayList)) {
                        // 删除索引
                        //DROP INDEX \"indexName\",
                        //ADD UNIQUE INDEX \"indexName\"(\"application_id\", \"is_deleted\"),
                        // 添加索引
                        String indexColumns = lazyTableFieldEndpoints.stream().
                                map(LazyTableFieldEndpoint::getColumnName).
                                collect(Collectors.joining(NormalUsedString.COMMA));
                        modifySqlList.add(String.format("DROP INDEX IF EXISTS \"%s\" ON %s", indexName, getFullTableName()));
                        // CREATE UNIQUE INDEX idx_users_email ON users(email);
                        modifySqlList.add(String.format("CREATE UNIQUE INDEX IF NOT EXISTS \"%s\" ON %s(%s)", indexName, getFullTableName(), indexColumns));
                    }
                } else {
                    // 添加索引
                    String indexColumns = lazyTableFieldEndpoints.stream().
                            map(LazyTableFieldEndpoint::getColumnName).
                            collect(Collectors.joining(NormalUsedString.COMMA));
                    modifySqlList.add(String.format("CREATE UNIQUE INDEX IF NOT EXISTS \"%s\" ON %s(%s)", indexName, getFullTableName(), indexColumns));
                }
            });
        }


        // 常用索引
        Map<String, List<LazyTableFieldEndpoint>> currentColumnNormalIndex = currentLayerFieldTypeMap.get(LayerField.LayerFieldType.NORMAL);

        Map<String, List<LazyTableFieldEndpoint>> javaColumnNormalIndex = javaLayerFieldTypeMap.get(LayerField.LayerFieldType.NORMAL);
        if (!ObjectUtils.isEmpty(javaColumnNormalIndex)) {
            javaColumnNormalIndex.forEach((indexName, lazyTableFieldEndpoints) -> {
                indexName = ObjectUtils.isEmpty(indexName) ?
                        lazyTableFieldEndpoints.stream().sorted(Comparator.comparing(LazyTableFieldEndpoint::getColumnName)).map(lazyTableFieldEndpoint -> lazyTableFieldEndpoint.getColumnName().replaceAll(NormalUsedString.BACKTICK, NormalUsedString.EMPTY).substring(0, 1))
                                .collect(Collectors.joining(NormalUsedString.UNDERSCORE)) :
                        indexName;
                if (!ObjectUtils.isEmpty(currentColumnNormalIndex) && currentColumnNormalIndex.containsKey(indexName)) {
                    // 判断是否修改索引
                    List<LazyTableFieldEndpoint> indexLazyTableFieldEndpoints = currentColumnNormalIndex.get(indexName);

                    // 重复数据
                    ArrayList<LazyTableFieldEndpoint> duplicateList = new ArrayList<>(lazyTableFieldEndpoints);
                    duplicateList.addAll(indexLazyTableFieldEndpoints);
                    ArrayList<LazyTableFieldEndpoint> tableFieldEndpointArrayList =
                            duplicateList
                                    .stream()
                                    .collect(
                                            Collectors.collectingAndThen(Collectors.toCollection(() ->
                                                            new TreeSet<>(Comparator.comparing(LazyTableFieldEndpoint::getColumnName))),
                                                    ArrayList::new));
                    // 不完全重复
                    if (!ObjectUtils.isEmpty(tableFieldEndpointArrayList)) {
                        // 删除索引
                        //DROP INDEX \"indexName\",
                        //ADD  INDEX \"indexName\"(\"application_id\", \"is_deleted\"),
                        // 添加索引
                        String indexColumns = lazyTableFieldEndpoints.stream().
                                map(lazyTableFieldEndpoint -> NormalUsedString.BACKTICK + lazyTableFieldEndpoint.getColumnName() + NormalUsedString.BACKTICK).
                                collect(Collectors.joining(NormalUsedString.COMMA));
                        modifySqlList.add(String.format("DROP INDEX \"%s\" ON %s ", indexName,getFullTableName()));
                        modifySqlList.add(String.format("CREATE  INDEX IF NOT EXISTS \"%s\"  ON %s(%s)", indexName, getFullTableName(), indexColumns));
                    }
                } else {
                    // 添加索引
                    String indexColumns = lazyTableFieldEndpoints.stream().
                            map(LazyTableFieldEndpoint::getColumnName).
                            collect(Collectors.joining(NormalUsedString.COMMA));
                    modifySqlList.add(String.format("CREATE  INDEX IF NOT EXISTS \"%s\" ON %s(%s)", indexName, getFullTableName(), indexColumns));
                }
            });
        }


        if (ObjectUtils.isEmpty(ADD_SQL_LIST) && ObjectUtils.isEmpty(modifySqlList)) {
            return modifySqlList;
        }
        // 最终的两段sql  添加字sql和更改sql
        modifySqlList.addAll(ADD_SQL_LIST);
        return modifySqlList;
    }

    /**
     * 创建每个字段修改的语句
     *
     * @param currentColumnNameList 当前数据库字段
     * @param dropColumn            是否删除列
     * @return
     */
    @Override
    public List<String> alterTableColumnSQL(List<H2ColumnEndpoint> currentColumnNameList, boolean dropColumn) {
        List<String> sql = alterTableColumnSQLPartList(currentColumnNameList, dropColumn);
        return sql.stream().filter(columnSql -> !ObjectUtils.isEmpty(columnSql)).collect(Collectors.toList());
    }


    /**
     * 获取指定注解的字段
     *
     * @param layerFieldType
     * @return
     */
    @Override
    public List<H2ColumnEndpoint> specifiedFieldAnnotation(LayerField.LayerFieldType layerFieldType) {
        List<H2ColumnEndpoint> lazyTableFieldEndpoints = new ArrayList<>();
        final List<H2ColumnEndpoint> fieldEndpoints = getLazyTableFieldEndpointList();
        if (ObjectUtils.isEmpty(fieldEndpoints)) {
            return lazyTableFieldEndpoints;
        }
        lazyTableFieldEndpoints =
                fieldEndpoints.stream().filter(lazyTableFieldEndpoint ->
                        Arrays.stream(lazyTableFieldEndpoint.getLazyTableIndexEndpoints()).
                                anyMatch(lazyTableIndexEndpoint -> lazyTableIndexEndpoint.getFieldIndexType().equals(layerFieldType))
                ).collect(Collectors.toList());
        return lazyTableFieldEndpoints;
    }

    /**
     * 获取当前字段对应的实例对象
     *
     * @return
     */
    @Override
    public H2ColumnEndpoint createLazyTableFieldEndpointInstance() {
        return new H2ColumnEndpoint();
    }


//    public static class FieldLazyTableFieldEndpoint extends AbstractLazyTableFieldEndpoint {
//
//    }
}


